import OSS from 'ali-oss';

// 初始化 OSS 客户端
const client = new OSS({
  region: 'oss-cn-hangzhou',
  accessKeyId: 'LTAI5tHroG1zkWxj5Er8CVdQ',
  accessKeySecret: 'S9gG9LLA5EHiCYxfA54sWMeWUKxlIO',
  authorizationV4: true,
  bucket: 'care-spirit-bucket',
});

/**
 * 获取文件的 Content-Type
 * @param {File} file - 文件对象
 * @returns {string} Content-Type
 */
function getContentType(file) {
  const ext = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
  
  // 视频类型
  const videoTypes = {
    '.mp4': 'video/mp4',
    '.avi': 'video/x-msvideo',
    '.mov': 'video/quicktime',
    '.wmv': 'video/x-ms-wmv',
    '.flv': 'video/x-flv',
    '.webm': 'video/webm',
    '.mkv': 'video/x-matroska',
    '.mpeg': 'video/mpeg',
    '.mpg': 'video/mpeg',
    '.m4v': 'video/mp4',
  };
  
  // 图片类型
  const imageTypes = {
    '.jpg': 'image/jpeg',
    '.jpeg': 'image/jpeg',
    '.png': 'image/png',
    '.gif': 'image/gif',
    '.bmp': 'image/bmp',
    '.webp': 'image/webp',
  };
  
  return videoTypes[ext] || imageTypes[ext] || file.type || 'application/octet-stream';
}

/**
 * 获取文件扩展名
 * @param {File} file - 文件对象
 * @returns {string} 扩展名（不含点）
 */
function getFileExtension(file) {
  const ext = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
  return ext.substring(1); // 去掉点号
}

/**
 * 生成唯一ID（时间戳 + 随机字符串）
 * @returns {string} 唯一ID，格式：{timestamp}_{random}
 */
function generateUniqueId() {
  const timestamp = Date.now();
  const random = Math.random().toString(36).substring(2, 9);
  return `${timestamp}_${random}`;
}

/**
 * 验证手机号是否有效
 * @param {string} phone - 手机号
 * @throws {Error} 如果手机号无效
 */
function validatePhone(phone) {
  if (!phone || phone === undefined || phone === null || (typeof phone === 'string' && phone.trim() === '')) {
    throw new Error('用户手机号不能为空');
  }
}

/**
 * 上传封面图片到 OSS
 * @param {File} file - 图片文件对象
 * @param {string} phone - 用户手机号
 * @param {string} courseId - 课程ID
 * @param {Function} onProgress - 进度回调函数 (progress) => void
 * @returns {Promise<string>} OSS 路径
 */
export async function uploadCoverImage(file, phone, courseId, onProgress) {
  try {
    // 构建 OSS 路径：thumbs/手机号/courseId/thumb.图片后缀名
    const ext = getFileExtension(file);
    const ossPath = `thumbs/${phone}/${courseId}/thumb.${ext}`;
    
    console.log('开始上传封面图片:', ossPath);
    
    // 配置上传选项
    const headers = {
      'x-oss-storage-class': 'Standard',
      'x-oss-object-acl': 'private',
      'Content-Type': getContentType(file),
      'Content-Disposition': 'inline',
      'Cache-Control': 'max-age=604800',
    };
    
    // 上传文件
    const result = await client.put(ossPath, file, {
      headers,
      progress: (p) => {
        if (onProgress) {
          onProgress(p);
        }
      },
    });
    
    console.log('封面图片上传成功:', ossPath);
    return ossPath;
  } catch (error) {
    console.error('封面图片上传失败:', error);
    throw new Error(`封面图片上传失败: ${error.message}`);
  }
}

/**
 * 上传海报图片到 OSS
 * @param {File} file - 图片文件对象
 * @param {string} phone - 用户手机号
 * @param {string} courseId - 课程ID
 * @param {Function} onProgress - 进度回调函数 (progress) => void
 * @returns {Promise<string>} OSS 路径
 */
export async function uploadPosterImage(file, phone, courseId, onProgress) {
  try {
    // 构建 OSS 路径：thumbs/手机号/courseId/poster.图片后缀名
    const ext = getFileExtension(file);
    const ossPath = `thumbs/${phone}/${courseId}/poster.${ext}`;
    
    console.log('开始上传海报图片:', ossPath);
    
    // 配置上传选项
    const headers = {
      'x-oss-storage-class': 'Standard',
      'x-oss-object-acl': 'private',
      'Content-Type': getContentType(file),
      'Content-Disposition': 'inline',
      'Cache-Control': 'max-age=604800',
    };
    
    // 上传文件
    const result = await client.put(ossPath, file, {
      headers,
      progress: (p) => {
        if (onProgress) {
          onProgress(p);
        }
      },
    });
    
    console.log('海报图片上传成功:', ossPath);
    return ossPath;
  } catch (error) {
    console.error('海报图片上传失败:', error);
    throw new Error(`海报图片上传失败: ${error.message}`);
  }
}

/**
 * 上传案例图片到 OSS
 * @param {File} file - 图片文件对象
 * @param {string} phone - 用户手机号
 * @param {string} timestamp - 时间戳（用于创建唯一目录）
 * @param {number} index - 图片索引（从1开始，用于pic1, pic2等）
 * @param {Function} onProgress - 进度回调函数 (progress) => void
 * @returns {Promise<string>} OSS 路径
 */
export async function uploadCaseImage(file, phone, timestamp, index, onProgress) {
  try {
    // 构建 OSS 路径：casePics/手机号/时间戳/pic{index}.图片后缀名
    const ext = getFileExtension(file);
    const ossPath = `casePics/${phone}/${timestamp}/pic${index}.${ext}`;
    
    console.log(`开始上传案例图片 ${index}:`, ossPath);
    
    // 配置上传选项
    const headers = {
      'x-oss-storage-class': 'Standard',
      'x-oss-object-acl': 'private',
      'Content-Type': getContentType(file),
      'Content-Disposition': 'inline',
      'Cache-Control': 'max-age=604800',
    };
    
    // 上传文件
    const result = await client.put(ossPath, file, {
      headers,
      progress: (p) => {
        if (onProgress) {
          onProgress(p);
        }
      },
    });
    
    console.log(`案例图片 ${index} 上传成功:`, ossPath);
    return ossPath;
  } catch (error) {
    console.error(`案例图片 ${index} 上传失败:`, error);
    throw new Error(`案例图片上传失败: ${error.message}`);
  }
}

/**
 * 上传视频到 OSS
 * @param {File} file - 视频文件对象
 * @param {string} phone - 用户手机号
 * @param {string} courseId - 课程ID
 * @param {number} index - 视频索引（从0开始，用于日志显示）
 * @param {Function} onProgress - 进度回调函数 (progress) => void
 * @param {Object} options - 可选参数
 * @param {boolean} options.useIndex - 是否使用索引命名（默认false，使用唯一ID）
 * @returns {Promise<string>} OSS 路径
 */
export async function uploadVideo(file, phone, courseId, index, onProgress, options = {}) {
  try {
    validatePhone(phone);
    
    const ext = getFileExtension(file);
    let ossPath;
    
    // 默认使用唯一ID命名（带时间戳），如果指定 useIndex 则使用索引命名
    if (options.useIndex) {
      // 使用索引命名：videos/手机号/courseId/episode{index+1}.视频后缀名
      ossPath = `videos/${phone}/${courseId}/episode${index + 1}.${ext}`;
      console.log(`开始上传视频 ${index + 1}（索引命名）:`, ossPath);
    } else {
      // 使用唯一ID命名：videos/手机号/courseId/video_{uniqueId}.视频后缀名
      const uniqueId = generateUniqueId();
      ossPath = `videos/${phone}/${courseId}/video_${uniqueId}.${ext}`;
      console.log(`开始上传视频 ${index + 1}（唯一ID: ${uniqueId}）:`, ossPath);
    }
    
    // 配置上传选项
    const headers = {
      'x-oss-storage-class': 'Standard',
      'x-oss-object-acl': 'private',
      'Content-Type': getContentType(file),
      'Content-Disposition': 'inline',
      'Cache-Control': 'max-age=604800',
    };
    
    // 根据文件大小选择上传方式
    const fileSizeMB = file.size / 1024 / 1024;
    let result;
    
    if (fileSizeMB < 100) {
      // 小于 100MB 使用普通上传
      result = await client.put(ossPath, file, {
        headers,
        progress: (p) => {
          if (onProgress) {
            onProgress(p);
          }
        },
      });
    } else {
      // 大于 100MB 使用分片上传
      result = await client.multipartUpload(ossPath, file, {
        headers,
        parallel: 4,
        partSize: 1024 * 1024 * 2, // 2MB per part
        progress: (p) => {
          if (onProgress) {
            onProgress(p);
          }
        },
        timeout: 120000, // 2分钟
      });
    }
    
    console.log(`视频 ${index + 1} 上传成功:`, ossPath);
    return ossPath;
  } catch (error) {
    console.error(`视频 ${index + 1} 上传失败:`, error);
    throw new Error(`视频 ${index + 1} 上传失败: ${error.message}`);
  }
}

/**
 * 批量上传视频
 * @param {File[]} files - 视频文件数组
 * @param {string} phone - 用户手机号
 * @param {string} courseId - 课程ID
 * @param {Function} onProgress - 进度回调函数 (index, progress) => void
 * @returns {Promise<string[]>} OSS 路径数组
 */
export async function uploadVideos(files, phone, courseId, onProgress) {
  const ossPaths = [];
  
  for (let i = 0; i < files.length; i++) {
    const ossPath = await uploadVideo(
      files[i],
      phone,
      courseId,
      i,
      (progress) => {
        if (onProgress) {
          onProgress(i, progress);
        }
      }
    );
    ossPaths.push(ossPath);
  }
  
  return ossPaths;
}

/**
 * 删除封面图片
 * @param {string} ossPath - OSS文件路径
 * @returns {Promise<void>}
 */
export async function deleteCoverImage(ossPath) {
  try {
    console.log('开始删除封面图片:', ossPath);
    await client.delete(ossPath);
    console.log('封面图片删除成功:', ossPath);
  } catch (error) {
    console.error('封面图片删除失败:', error);
    throw new Error(`封面图片删除失败: ${error.message}`);
  }
}

/**
 * 删除海报图片
 * @param {string} ossPath - OSS文件路径
 * @returns {Promise<void>}
 */
export async function deletePosterImage(ossPath) {
  try {
    console.log('开始删除海报图片:', ossPath);
    await client.delete(ossPath);
    console.log('海报图片删除成功:', ossPath);
  } catch (error) {
    console.error('海报图片删除失败:', error);
    throw new Error(`海报图片删除失败: ${error.message}`);
  }
}

/**
 * 删除单个视频
 * @param {string} ossPath - OSS文件路径
 * @returns {Promise<void>}
 */
export async function deleteVideo(ossPath) {
  try {
    console.log('开始删除视频:', ossPath);
    await client.delete(ossPath);
    console.log('视频删除成功:', ossPath);
  } catch (error) {
    console.error('视频删除失败:', error);
    throw new Error(`视频删除失败: ${error.message}`);
  }
}

/**
 * 删除单个案例图片
 * @param {string} ossPath - OSS文件路径
 * @returns {Promise<void>}
 */
export async function deleteCaseImage(ossPath) {
  try {
    console.log('开始删除案例图片:', ossPath);
    await client.delete(ossPath);
    console.log('案例图片删除成功:', ossPath);
  } catch (error) {
    console.error('案例图片删除失败:', error);
    throw new Error(`案例图片删除失败: ${error.message}`);
  }
}

/**
 * 批量删除案例图片
 * @param {string[]} ossPaths - OSS文件路径数组
 * @returns {Promise<Object>} 删除结果
 */
export async function deleteCaseImages(ossPaths) {
  try {
    if (!ossPaths || ossPaths.length === 0) {
      console.log('没有需要删除的案例图片');
      return { deleted: [], failed: [] };
    }

    console.log('开始批量删除案例图片:', ossPaths);
    
    // 使用 deleteMulti 批量删除
    const result = await client.deleteMulti(ossPaths, {
      quiet: false, // 返回详细的删除结果
    });
    
    console.log('案例图片批量删除成功:', result);
    return {
      deleted: result.deleted || ossPaths,
      failed: result.failed || [],
    };
  } catch (error) {
    console.error('案例图片批量删除失败:', error);
    throw new Error(`案例图片批量删除失败: ${error.message}`);
  }
}

/**
 * 批量删除视频
 * @param {string[]} ossPaths - OSS文件路径数组
 * @returns {Promise<Object>} 删除结果
 */
export async function deleteVideos(ossPaths) {
  try {
    if (!ossPaths || ossPaths.length === 0) {
      console.log('没有需要删除的视频');
      return { deleted: [], failed: [] };
    }

    console.log('开始批量删除视频:', ossPaths);
    
    // 使用 deleteMulti 批量删除
    const result = await client.deleteMulti(ossPaths, {
      quiet: false, // 返回详细的删除结果
    });
    
    console.log('视频批量删除成功:', result);
    return {
      deleted: result.deleted || ossPaths,
      failed: result.failed || [],
    };
  } catch (error) {
    console.error('视频批量删除失败:', error);
    throw new Error(`视频批量删除失败: ${error.message}`);
  }
}

/**
 * 删除课程的所有文件（封面、海报、视频）
 * @param {string} phone - 用户手机号
 * @param {string} courseId - 课程ID
 * @param {Object} options - 可选参数
 * @param {boolean} options.deleteCover - 是否删除封面（默认true）
 * @param {boolean} options.deletePoster - 是否删除海报（默认true）
 * @param {number} options.videoCount - 视频数量（如果不提供，将尝试删除前20个视频）
 * @returns {Promise<Object>} 删除结果
 */
export async function deleteCourseFiles(phone, courseId, options = {}) {
  const {
    deleteCover = true,
    deletePoster = true,
    videoCount,
  } = options;

  const results = {
    success: [],
    failed: [],
  };

  try {
    console.log(`开始删除课程文件 (courseId: ${courseId})`);

    // 收集需要删除的文件路径
    const pathsToDelete = [];

    // 添加封面图片路径（可能的扩展名）
    if (deleteCover) {
      const coverExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
      for (const ext of coverExtensions) {
        pathsToDelete.push(`thumbs/${phone}/${courseId}/thumb.${ext}`);
      }
    }

    // 添加海报图片路径（可能的扩展名）
    if (deletePoster) {
      const posterExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
      for (const ext of posterExtensions) {
        pathsToDelete.push(`thumbs/${phone}/${courseId}/poster.${ext}`);
      }
    }

    // 添加视频路径
    const maxVideos = videoCount || 20; // 默认尝试删除前20个视频
    const videoExtensions = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv'];
    for (let i = 1; i <= maxVideos; i++) {
      for (const ext of videoExtensions) {
        pathsToDelete.push(`videos/${phone}/${courseId}/episode${i}.${ext}`);
      }
    }

    // 批量删除所有文件
    if (pathsToDelete.length > 0) {
      const result = await client.deleteMulti(pathsToDelete, {
        quiet: true, // 静默模式，不返回详细信息（某些文件可能不存在）
      });

      console.log(`课程文件删除完成 (courseId: ${courseId})`);
      results.success = pathsToDelete;
    }

    return results;
  } catch (error) {
    console.error('课程文件删除失败:', error);
    results.failed.push(error.message);
    throw new Error(`课程文件删除失败: ${error.message}`);
  }
}

/**
 * 删除指定路径下的所有文件（使用列举+删除的方式）
 * @param {string} prefix - 路径前缀，例如 'videos/13800000000/course123/'
 * @returns {Promise<Object>} 删除结果
 */
export async function deleteByPrefix(prefix) {
  try {
    console.log('开始删除指定路径下的所有文件:', prefix);
    
    // 列举所有文件
    const result = await client.list({
      prefix: prefix,
      'max-keys': 1000,
    });

    if (!result.objects || result.objects.length === 0) {
      console.log('未找到需要删除的文件');
      return { deleted: [], count: 0 };
    }

    // 提取文件名
    const objectNames = result.objects.map(obj => obj.name);
    
    console.log(`找到 ${objectNames.length} 个文件，开始删除...`);

    // 批量删除
    const deleteResult = await client.deleteMulti(objectNames, {
      quiet: false,
    });

    console.log('删除完成:', deleteResult);
    
    return {
      deleted: deleteResult.deleted || objectNames,
      count: objectNames.length,
    };
  } catch (error) {
    console.error('按前缀删除文件失败:', error);
    throw new Error(`按前缀删除文件失败: ${error.message}`);
  }
}

export default {
  // 上传方法
  uploadCoverImage,
  uploadPosterImage,
  uploadCaseImage,
  uploadVideo,
  uploadVideos,
  // 删除方法
  deleteCoverImage,
  deletePosterImage,
  deleteCaseImage,
  deleteCaseImages,
  deleteVideo,
  deleteVideos,
  deleteCourseFiles,
  deleteByPrefix,
  // OSS客户端
  client,
};

